﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using jQuery.WebControls;


namespace jQuery.WebControls.UI
{
    /// <summary>
    /// Control formado por un TextBox que incorpora un DatePicker de jQuery UI para seleccionar una fecha en concreto
    /// </summary>
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:DateTextBox runat=server></{0}:DateTextBox>")]
    public class DateTextBox : TextBox
    {          
        private ClientScriptProxy scriptManager;
        private jQueryScriptManager jQueryMngr;
                
        
        #region "PROPIEDADES"
        private jQueryScriptManager jQueryManager
        {
            get 
            {
                if (jQueryMngr == null)
                    jQueryMngr = Common.Instance.Get_jQueryScriptManager(Page);
                return jQueryMngr; 
            }
        }

        /// <summary>
        /// Set the name of the animation used to show/hide the datepicker. Use 'show' (the default), 'slideDown', 'fadeIn', any of the show/hide jQuery UI effects, or '' for no animation
        /// </summary>
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue(Effect.None)]
        [Localizable(true)]
        public Effect ShowAnimation
        {
            get
            {
                if (ViewState["dpsa"] == null)
                {
                    ViewState["dpsa"] = Effect.None;
                }
                return (Effect)Enum.Parse(typeof(Effect), ViewState["dpsa"].ToString());
            }
            set
            {
                ViewState["dpsa"] = value;
            }
        }
        /// <summary>
        /// Gets or sets how many months to move when clicking the Previous/Next links
        /// </summary>
        /// <exception cref="ArgumentException">StepMonths has to be an integer between 1 and 12</exception>
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("1")]
        [Localizable(true)]
        public int StepMonths
        {
            get
            {
                if (ViewState["sm"] == null)
                {
                    ViewState["sm"] = 1;
                }
                return int.Parse(ViewState["sm"].ToString());
            }
            set
            {
                if (value > 0 && value < 13)
                {
                    ViewState["sm"] = value;
                }
                else
                {
                    throw new ArgumentException("StepMonths has to be an integer between 1 and 12");
                }
            }
        }
        /// <summary>
        /// Gets or sets how many months to show at once. The value can be a straight integer, or can be a two-element array to define the number of rows and columns to display.
        /// <para><example>2, 3</example></para>
        /// </summary>
        /// <exception cref="ArgumentException">You can not declare an array with more than 2 dimensions</exception>
        /// <exception cref="ArgumentException">Both values must be integer</exception>
        /// <exception cref="ArgumentException">The multiplication of the 2 axes can not exceed 12</exception>
        /// <exception cref="ArgumentException">NumberOfMonths has to be an integer between 1 and 12</exception>
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("1")]
        [Localizable(true)]
        public string NumberOfMonths
        {
            get
            {
                if (ViewState["nm"] == null)
                {
                    ViewState["nm"] = "1";
                }
                return ViewState["nm"].ToString();
            }
            set
            {
                if (value.IndexOf(",") > 0)
                {
                    int aux = 0;
                    string[] coor = value.Split(',');
                    if (coor.Length > 2)
                    {
                        throw new ArgumentException(jQuery.Messages.DTB_err1);
                    }
                    else
                    {
                        
                        if(!int.TryParse(coor[0], out aux) || !int.TryParse(coor[1], out aux))
                        {
                            throw new ArgumentException(jQuery.Messages.DTB_err2);
                        }
                    }
                    aux = int.Parse(coor[0]) * int.Parse(coor[1]);
                    if (aux > 0 && aux < 13)
                    {
                        ViewState["nm"] = value;
                    }
                    else
                    {
                        throw new ArgumentException(jQuery.Messages.DTB_err3);
                    }                    
                }
                else
                {
                    int aux = 0;
                    if (!int.TryParse(value, out aux))
                    {
                        throw new ArgumentException(jQuery.Messages.DTB_err4);
                    }
                    else if (aux > 0 && aux < 13)
                    {
                        ViewState["nm"] = value;
                    }
                    else
                    {
                        throw new ArgumentException(jQuery.Messages.DTB_err5);
                    }                    
                }                
            }
        }

        /// <summary>
        /// Gets or sets if the control must allows to change the year with a drop down list
        /// </summary>
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Gets or sets if the control must allows to change the year with a drop down list")]
        public bool ChangeYear
        {
            get
            {
                if (ViewState["chy"] == null)
                {
                    ViewState.Add("chy", jQueryManager.ChangeYear);
                }
                return bool.Parse(ViewState["chy"].ToString());
            }
            set
            {
                ViewState["chy"] = value;
            }
        }
        
        /// <summary>
        /// Gets or sets if the control must allows to change the month with a drop down list 
        /// </summary>
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Gets or sets if the control must allows to change the month with a drop down list")]
        public bool ChangeMonth
        {
            get
            {
                if ( ViewState["chm"]== null)
                {
                    ViewState.Add("chm", jQueryManager.ChangeMonth);
                }
                return bool.Parse(ViewState["chm"].ToString());
            }
            set
            {
                ViewState["chm"] = value;
            }
        }

        private bool HasSpecificOptions
        {
            get
            {
                if (ViewState["chy"] == null && ViewState["chm"] == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
        /// <summary>
        /// Gets the input date of the control or DateTime.MinValue if it's empty or it's not a correct date
        /// Devuelve la fecha introducida en el DateTextBox o DateTime.MinValue 
        /// si está vacio o no se puede convertir
        /// </summary>
        public DateTime Value
        {
            get
            {
                DateTime aux = DateTime.MinValue;
                DateTime.TryParse(Text, out aux);
                return aux;
            }
        }
        private bool aEnabledDialog = true;
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Gets or sets if the control must display the date picker dialog")]
        public bool EnabledDialog { get { return aEnabledDialog; } set { aEnabledDialog = value; } }

        #endregion

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!Page.IsPostBack)
            {
                if (!DesignMode)
                    CheckQueryManager();
            }
        }

        protected override void OnLoad(EventArgs e)
        {            
            base.OnLoad(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (!ReadOnly && Enabled && EnabledDialog)
            {
                if (jQueryManager.ChangeMonth != ChangeMonth || 
                    jQueryManager.ChangeYear != ChangeYear || 
                    jQueryManager.DatePickerShowAnimation != ShowAnimation || 
                    jQueryManager.DatePickerStepMonths != StepMonths)
                {
                    string options = "";
                    if (ShowAnimation != Effect.None)
                    {
                        options = String.Format(", showAnim:'{0}'", ShowAnimation.ToString().ToLower());
                    }
                    else if (jQueryManager.DatePickerShowAnimation != Effect.None)
                    {
                        options = String.Format(", showAnim:'{0}'", jQueryManager.DatePickerShowAnimation.ToString().ToLower());
                    }
                    if (jQueryManager.DatePickerStepMonths != StepMonths)
                    {
                        options = String.Format("{0}, stepMonths: {1}", options, StepMonths);
                    }
                    if (!NumberOfMonths.Equals("1"))
                    {
                        if (NumberOfMonths.IndexOf(",") > 0)
                        {
                            options = String.Format("{0}, numberOfMonths: [{1}]", options, NumberOfMonths);
                        }
                        else
                        {
                            options = String.Format("{0}, numberOfMonths: {1}", options, NumberOfMonths);
                        }
                    }
                    string script = "$(function() {$('#" + this.ClientID + "').datepicker({changeMonth:" + ChangeMonth.ToString().ToLower() +
                        ", changeYear:" + ChangeYear.ToString().ToLower() + options + "});});";
                    ClientScriptProxy.RegisterClientScriptBlock(this, GetType(), String.Format("calendar_{0}", ClientID), script, true);
                }
                else if (!CssClass.Contains("DateTextBoxPicker"))
                {
                    base.CssClass = String.Format("DateTextBoxPicker {0}", CssClass);
                }
            }
            else
            {
                if (CssClass.Contains("DateTextBoxPicker"))
                {
                    CssClass = CssClass.Replace("DateTextBoxPicker", "");
                }

            }
            base.OnPreRender(e);
        }

        private ClientScriptProxy ClientScriptProxy
        {
            get
            {
                if (scriptManager == null)
                {
                    scriptManager = ClientScriptProxy.Current;
                }
                return scriptManager;
            }
        }


        private void CheckQueryManager()
        {
            Common.Instance.CheckJQueryScriptManager(Page);
        }
    }
}
